package com.wiscamp.ninechapters.panels.infrastructure.repositories;


import com.wiscamp.ninechapters.panels.domain.entities.Application;
import com.wiscamp.ninechapters.panels.domain.repositories.ApplicationRepository;
import com.wiscamp.ninechapters.panels.infrastructure.converters.ApplicationConverter;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.ApplicationMapper;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.ApplicationViewMapper;
import com.wiscamp.ninechapters.panels.infrastructure.po.ApplicationPO;
import com.wiscamp.ninechapters.panels.infrastructure.views.ApplicationView;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.PersistenceUtils;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class ApplicationRepositoryImpl implements ApplicationRepository {

    private final ApplicationMapper applicationMapper;

    private final ApplicationViewMapper applicationViewMapper;

    public ApplicationRepositoryImpl(ApplicationMapper applicationMapper, ApplicationViewMapper applicationViewMapper) {
        this.applicationMapper = applicationMapper;
        this.applicationViewMapper = applicationViewMapper;
    }

    private ApplicationPO getApplicationPO(long appId) {
        return PersistenceUtils.findById(appId, applicationMapper::findById);
    }

    @HandleDataException
    public Application getApplication(long appId) {
        return PersistenceUtils.findEntityById(appId, applicationViewMapper::findById,
                ApplicationConverter.Instance::toApplicationByView);

    }

    @HandleDataException
    public Application getApplicationByCode(String appCode) {
        return PersistenceUtils.getEntityByText(appCode, applicationViewMapper::findByApplicationCode,
                ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public Collection<Application> getApplicationsByIds(Collection<Long> appIds) {
        return PersistenceUtils.getEntitiesByIds(appIds, applicationViewMapper::findAllById,
                ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public Collection<Application> getApplicationsByGroup(String appGroup) {
        return PersistenceUtils.getEntitiesByText(appGroup, applicationViewMapper::findListByApplicationGroup,
                ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public Collection<Application> getAvailableApplications() {
        return PersistenceUtils.getEntities(applicationViewMapper::findListByAvailable,
                ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public Collection<Application> getApplicationsByName(String appName) {
        return PersistenceUtils.getEntitiesByText(appName, applicationViewMapper::findListByApplicationName,
                ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public PagedObjects<Application> getApplicationsByQuery(PagedQuery query) {
        PagedObjects<ApplicationView> pagedObjects = PersistenceUtils.getPersistenceObjectsByQuery(query, applicationViewMapper::findAll);
        return PersistenceUtils.convertPagedObjects(pagedObjects, ApplicationConverter.Instance::toApplicationByView);
    }

    @HandleDataException
    public Application saveApplication(Application app) {
        if (app.getApplicationId() <= 0) {
            return PersistenceUtils.createEntity(app, applicationMapper::saveAndFlush,
                    ApplicationConverter.Instance::toApplicationPO, ApplicationConverter.Instance::toApplication);
        } else {
            var existedPO = getApplicationPO(app.getApplicationId());
            if (existedPO == null) existedPO = new ApplicationPO();
            return PersistenceUtils.updateEntity(app, existedPO, applicationMapper::saveAndFlush,
                    ApplicationConverter.Instance::toApplicationPO, ApplicationConverter.Instance::toApplication);
        }
    }

    /*@HandleDataException
    public Application createApplication(Application app) {
        return PersistenceUtils.createEntity(app, applicationMapper::saveAndFlush,
                ApplicationConverter.Instance::toApplicationPO, ApplicationConverter.Instance::toApplication);
    }

    @HandleDataException
    public Application updateApplication(Application app) {
        var existedPO = getApplicationPO(app.getApplicationId());
        if (existedPO == null) existedPO = new ApplicationPO();
        return PersistenceUtils.updateEntity(app, existedPO, applicationMapper::saveAndFlush,
                ApplicationConverter.Instance::toApplicationPO, ApplicationConverter.Instance::toApplication);
    }*/
}
